package com.bowlong.util;

import java.io.IOException;
import java.util.Arrays;

import org.apache.commons.logging.LogFactory;

import com.bowlong.lang.ThreadEx;
import com.bowlong.objpool.StringBufPool;

@SuppressWarnings({})
public class Log {
	static org.apache.commons.logging.Log log = LogFactory.getLog(Log.class);
	// static ExecutorService ES;
	static boolean OPEN = true;

	public static void init(boolean open) {
		OPEN = open;
		if (!OPEN)
			return;

		// ES();
	}

	// public static final ExecutorService ES() {
	// if (ES == null)
	// ES = Executors.newSingleThreadExecutor();
	// return ES;
	// }

	// public static final void shutdown() {
	// if (ES != null) {
	// ES.shutdown();
	// ES = null;
	// }
	// }
	//
	// public static final void shutdownNow() {
	// if (ES != null) {
	// ES.shutdownNow();
	// ES = null;
	// }
	// }

	public static void trace(final Object message) {
		if (!OPEN)
			return;

		// Async.exec(ES(), new Runnable() {
		// public void run() {
		log.trace(message);
		// }
		// });
	}

	public static void trace(final Object message, final Throwable t) {
		if (!OPEN)
			return;

		// Async.exec(ES(), new Runnable() {
		// public void run() {
		String str = e2s(t, message);
		log.trace(str);
		// }
		// });
	}

	public static void debug(final Object message) {
		if (!OPEN)
			return;

		// Async.exec(ES(), new Runnable() {
		// public void run() {
		log.debug(message);
		// }
		// });
	}

	public static void debug(final Object message, final Throwable t) {
		if (!OPEN)
			return;

		// Async.exec(ES(), new Runnable() {
		// public void run() {
		String str = e2s(t, message);
		log.debug(str);
		// }
		// });
	}

	public static void info(final Object message) {
		if (!OPEN)
			return;

		// Async.exec(ES(), new Runnable() {
		// public void run() {
		log.info(message);
		// }
		// });
	}

	public static void info(final Object message, final Throwable t) {
		if (!OPEN)
			return;

		// Async.exec(ES(), new Runnable() {
		// public void run() {
		String str = e2s(t, message);
		log.info(str);
		// }
		// });
	}

	public static void warn(final Object message) {
		if (!OPEN)
			return;

		// Async.exec(ES(), new Runnable() {
		// public void run() {
		log.warn(message);
		// }
		// });
	}

	public static void warn(final Object message, final Throwable t) {
		if (!OPEN)
			return;

		// Async.exec(ES(), new Runnable() {
		// public void run() {
		String str = e2s(t, message);
		log.warn(str);
		// }
		// });
	}

	public static void error(final Object message) {
		if (!OPEN)
			return;

		// Async.exec(ES(), new Runnable() {
		// public void run() {
		log.error(message);
		// }
		// });
	}

	public static void error(final Object message, final Throwable t) {
		if (!OPEN)
			return;

		// Async.exec(ES(), new Runnable() {
		// public void run() {
		String str = e2s(t, message);
		log.error(str);
		// }
		// });
	}

	public static void fatal(final Object message) {
		if (!OPEN)
			return;

		// Async.exec(ES(), new Runnable() {
		// public void run() {
		log.fatal(message);
		// }
		// });
	}

	public static void fatal(final Object message, final Throwable t) {
		if (!OPEN)
			return;

		// Async.exec(ES(), new Runnable() {
		// public void run() {
		String str = e2s(t, message);
		log.fatal(str);
		// }
		// });
	}

	// //////////////////////////////////////////
	//
	// public static SQLException rethrow(SQLException cause, String sql)
	// throws SQLException {
	//
	// String causeMessage = cause.getMessage();
	// if (causeMessage == null) {
	// causeMessage = "";
	// }
	// StringBuffer msg = new StringBuffer(causeMessage);
	// msg.append("\r\n");
	// msg.append(" Query: ");
	// msg.append("\r\n");
	// msg.append(sql);
	// msg.append("\r\n");
	//
	// SQLException e = new SQLException(msg.toString(), cause.getSQLState(),
	// cause.getErrorCode());
	// e.setNextException(cause);
	//
	// return e;
	// }
	//
	// public static SQLException rethrow(SQLException cause, String sql,
	// Object... params) {
	//
	// String causeMessage = cause.getMessage();
	// if (causeMessage == null) {
	// causeMessage = "";
	// }
	// StringBuffer msg = new StringBuffer(causeMessage);
	// msg.append("\r\n");
	// msg.append(" Query: ");
	// msg.append("\r\n");
	// msg.append(sql);
	// msg.append("\r\n");
	// msg.append(" Parameters: ");
	// msg.append("\r\n");
	// if (params == null) {
	// msg.append("[]");
	// } else {
	// msg.append(Arrays.deepToString(params));
	// }
	// msg.append("\r\n");
	// SQLException e = new SQLException(msg.toString(), cause.getSQLState(),
	// cause.getErrorCode());
	// e.setNextException(cause);
	//
	// return e;
	// }
	//
	// public static SQLException rethrow(SQLException cause, String sql,
	// Map params) throws SQLException {
	//
	// String causeMessage = cause.getMessage();
	// if (causeMessage == null) {
	// causeMessage = "";
	// }
	// StringBuffer msg = new StringBuffer(causeMessage);
	// msg.append("\r\n");
	// msg.append(" Query: ");
	// msg.append("\r\n");
	// msg.append(sql);
	// msg.append("\r\n");
	// msg.append(" Parameters: ");
	// msg.append("\r\n");
	// if (params == null) {
	// msg.append("{}");
	// } else {
	// msg.append(FastJSON.prettyFormat(params));
	// // msg.append(JSON.toJSONStringNotExcept(params));
	// }
	// msg.append("\r\n");
	// SQLException e = new SQLException(msg.toString(), cause.getSQLState(),
	// cause.getErrorCode());
	// e.setNextException(cause);
	//
	// return e;
	// }
	//
	// public static SQLException rethrow(SQLException cause, String sql,
	// List params) throws SQLException {
	//
	// String causeMessage = cause.getMessage();
	// if (causeMessage == null) {
	// causeMessage = "";
	// }
	// StringBuffer msg = new StringBuffer(causeMessage);
	//
	// msg.append("\r\n");
	// msg.append(" Query: ");
	// msg.append("\r\n");
	// msg.append(sql);
	// msg.append("\r\n");
	// msg.append(" Parameters: ");
	// msg.append("\r\n");
	// if (params == null) {
	// msg.append("[]");
	// } else {
	// msg.append(FastJSON.prettyFormat(params));
	// // msg.append(JSON.toJSONStringNotExcept(params));
	// }
	// msg.append("\r\n");
	// SQLException e = new SQLException(msg.toString(), cause.getSQLState(),
	// cause.getErrorCode());
	// e.setNextException(cause);
	//
	// return e;
	// }

	// //////////////////////////////////////////

	public static Exception rethrow(Exception cause, String method,
			Object... params) {
		String causeMessage = cause.getMessage();
		if (causeMessage == null) {
			causeMessage = "";
		}
		StringBuffer msg = new StringBuffer(causeMessage);
		msg.append("\r\n");
		msg.append(method);
		msg.append(" Parameters: ");
		msg.append("\r\n");
		if (params == null) {
			msg.append("[]");
		} else {
			msg.append(Arrays.deepToString(params));
		}
		msg.append("\r\n");
		Exception e = new Exception(msg.toString(), cause);
		return e;
	}

	public static String rethrow2(Exception cause, String method,
			Object... params) {
		String causeMessage = cause.getMessage();
		if (causeMessage == null) {
			causeMessage = "";
		}
		StringBuffer msg = new StringBuffer(causeMessage);
		// msg.append("\r\n");
		e2s(msg, cause);
		// msg.append("\r\n");
		// msg.append("\r\n");
		msg.append(method);
		msg.append(" Parameters: ");
		msg.append("\r\n");
		if (params == null) {
			msg.append("[]");
		} else {
			msg.append(Arrays.deepToString(params));
		}
		return msg.toString();
	}

	public static final String e2s(final Throwable e) {
		return e2s(e, null, new Object[0]);
	}

	public static final String e2s(final StringBuffer sb, final Throwable e) {
		return e2s(sb, e, null, new Object[0]);
	}

	public static final String e2s(final Throwable e, final Object obj) {
		return e2s(e, String.valueOf(obj), new Object[0]);
	}

	public static final String e2s(final StringBuffer sb, final Throwable e,
			final Object obj) {
		return e2s(sb, e, String.valueOf(obj), new Object[0]);
	}

	public static String e2s(final Throwable e, final String fmt,
			final Object... args) {
		StringBuffer sb = StringBufPool.borrowObject();
		try {
			return e2s(sb, e, fmt, args);
		} finally {
			StringBufPool.returnObject(sb);
		}
	}

	public static String e2s(final StringBuffer sb, final Throwable e,
			final String fmt, final Object... args) {
		sb.append(e);
		if (fmt != null && !fmt.isEmpty() && args.length <= 0)
			sb.append(" - ").append(fmt);
		if (fmt != null && !fmt.isEmpty() && args.length > 0) {
			String str = StrBuilder.builder().ap(fmt, args).str();
			sb.append(" - ").append(str);
		}
		sb.append("\r\n");
		for (StackTraceElement ste : e.getStackTrace()) {
			sb.append("at ");
			sb.append(ste);
			sb.append("\r\n");
		}
		return sb.toString();
	}

	public static void main(String[] args) {
		p();
		ThreadEx.Sleep(1000);
	}

	public static void p() {
		if (!OPEN)
			return;

		Log.info(rethrow2(new IOException("xxx"), "p"));
	}

	public static void p(String s) {
		if (!OPEN)
			return;

		System.out.println(s);
	}
}
